import { Lexer, ListLexer, Token } from "../ch2";

/**
 * 语法解析器公共类
 */
class Parser {
    input: Lexer
    lookahead:Token | undefined;

    constructor(input:Lexer){
        this.input = input;
        this.consume();
    }

    /**
     * 匹配TokenType
     * @param tokenType 
     */
    match(tokenType:number){
        if(this.lookahead?.type == tokenType){
            this.consume();
        }else {
            throw new Error("expecting " + this.input.getTokenName(tokenType) + " found " + this.lookahead)
        }
    }

    /**
     * 移动到下一个Token
     */
    consume(){
        this.lookahead = this.input.nextToken();
    }
}

/**
 * 列表语法解析器
 */
class ListParser extends Parser {

    // list : '[' elements ']'
    list(){
        this.match(ListLexer.LBRACK);
        this.elements();
        this.match(ListLexer.RBRACK);
        console.log("---list ok");
    }
    // elements : element (',' element)*
    elements(){
        this.element();
        while(this.lookahead?.type == ListLexer.COMMA){
            this.match(ListLexer.COMMA);
            this.element();
        }
    }
    // element : NAME | list
    element(){
        if(this.lookahead?.type == ListLexer.NAME){
            this.match(ListLexer.NAME);
        }else if(this.lookahead?.type == ListLexer.LBRACK){
            this.list();
        }else{
            throw new Error("expecting name or list; found" + this.lookahead)
        }
    }
}

export {
    Parser,
    ListParser
}